Telegram Group »
United States »
Библиотека Python разработчика | Книги по питону » Telegram Webview
🚀 Подпишись и прокачай свои скилы: лучшие каналы для IT-специалистов 👨💻📲
Папка с каналами для DevOps, Linux - Windows СисАдминов👍
Папка с каналами для 1С программистов🧑💻
Папка с каналами для C++ программистов👩💻
Папка с каналами для Python программистов👩💻
Папка с каналами для Java программистов🖥
Папка с книгами для программистов 📚
Папка для программистов (frontend, backend, iOS, Android)💻
GitHub Сообщество🧑💻
https://www.tg-me.com/Githublib Интересное из GitHub
Базы данных (Data Base)🖥
https://www.tg-me.com/database_info Все про базы данных
Разработка игр📱
https://www.tg-me.com/game_devv Все о разработке игр
БигДата, машинное обучение🖥
https://www.tg-me.com/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning
QA, тестирование🖥
https://www.tg-me.com/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://www.tg-me.com/itumor Шутки программистов
Защита, взлом, безопасность💻
https://www.tg-me.com/thehaking Канал о кибербезопасности
https://www.tg-me.com/xakep_2 Хакер Free
Книги, статьи для дизайнеров🎨
https://www.tg-me.com/ux_web Статьи, книги для дизайнеров
Математика🧮
https://www.tg-me.com/Pomatematike Канал по математике
https://www.tg-me.com/phis_mat Обучающие видео, книги по Физике и Математике
Excel лайфхак🙃
https://www.tg-me.com/Excel_lifehack
Технологии🖥
https://www.tg-me.com/tikon_1 Новости высоких технологий, науки и техники💡
https://www.tg-me.com/mir_teh Мир технологий (Technology World)
Вакансии💰
https://www.tg-me.com/sysadmin_rabota Системный Администратор
https://www.tg-me.com/progjob Вакансии в IT
https://www.tg-me.com/rabota1C_rus Вакансии для программистов 1С
Папка с каналами для DevOps, Linux - Windows СисАдминов
Папка с каналами для 1С программистов
Папка с каналами для C++ программистов
Папка с каналами для Python программистов
Папка с каналами для Java программистов
Папка с книгами для программистов 📚
Папка для программистов (frontend, backend, iOS, Android)
GitHub Сообщество
https://www.tg-me.com/Githublib Интересное из GitHub
Базы данных (Data Base)
https://www.tg-me.com/database_info Все про базы данных
Разработка игр
https://www.tg-me.com/game_devv Все о разработке игр
БигДата, машинное обучение
https://www.tg-me.com/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning
QA, тестирование
https://www.tg-me.com/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://www.tg-me.com/itumor Шутки программистов
Защита, взлом, безопасность
https://www.tg-me.com/thehaking Канал о кибербезопасности
https://www.tg-me.com/xakep_2 Хакер Free
Книги, статьи для дизайнеров
https://www.tg-me.com/ux_web Статьи, книги для дизайнеров
Математика
https://www.tg-me.com/Pomatematike Канал по математике
https://www.tg-me.com/phis_mat Обучающие видео, книги по Физике и Математике
Excel лайфхак
https://www.tg-me.com/Excel_lifehack
Технологии
https://www.tg-me.com/tikon_1 Новости высоких технологий, науки и техники💡
https://www.tg-me.com/mir_teh Мир технологий (Technology World)
Вакансии
https://www.tg-me.com/sysadmin_rabota Системный Администратор
https://www.tg-me.com/progjob Вакансии в IT
https://www.tg-me.com/rabota1C_rus Вакансии для программистов 1С
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Админ Devops
You’ve been invited to add the folder “Админ Devops”, which includes 18 chats.
Функция
Однако если каждый элемент итерируемого объекта — это кортеж, было бы удобно передавать каждый элемент кортежа как отдельный аргумент. В Python 2 это было возможно благодаря распаковке параметров кортежа (обратите внимание на скобки):
В Python 3 эта возможность исчезла, но есть другое решение —
👉@BookPython
map
вызывает другую функцию для каждого элемента итерируемого объекта. Это значит, что функция должна принимать одно значение в качестве аргумента:
In : list(map(lambda x: x ** 2, [1, 2, 3]))
Out: [1, 4, 9]
Однако если каждый элемент итерируемого объекта — это кортеж, было бы удобно передавать каждый элемент кортежа как отдельный аргумент. В Python 2 это было возможно благодаря распаковке параметров кортежа (обратите внимание на скобки):
>>> map(lambda (a, b): a + b, [(1, 2), (3, 4)])
[3, 7]
В Python 3 эта возможность исчезла, но есть другое решение —
itertools.starmap
. Она распаковывает кортежи за вас, будто функция вызывается со звёздочкой: f(*arg)
(отсюда и название функции):
from itertools import starmap
In [3]: list(starmap(lambda a, b: a + b, [(1, 2), (3, 4)]))
Out[3]: [3, 7]
👉@BookPython
Лямбды в Python не могут делать многое из того, что умеют обычные функции. В теле лямбда-выражения можно использовать только одно выражение, нельзя писать операторы (такие как
Тем не менее, если очень нужно превратить лямбду в асинхронную функцию, можно использовать декоратор
Разумеется, это всё равно не позволяет использовать
👉@BookPython
a = b
, yield
, await
и т.д.), также нельзя добавлять аннотации типов или объявлять лямбду как async
.Тем не менее, если очень нужно превратить лямбду в асинхронную функцию, можно использовать декоратор
asyncio.coroutine
. Это было полезно до появления ключевого слова async
в Python 3.4, но в современном Python почти не применяется.
>>> f = asyncio.coroutine(lambda x: x ** 2)
>>> asyncio.get_event_loop().run_until_complete(f(12))
144
Разумеется, это всё равно не позволяет использовать
await
внутри лямбды.👉@BookPython
Когда вы используете модуль
Однако сериализация исключений может быть непростой задачей. Исключение создаётся с любым количеством аргументов, которые сохраняются в атрибуте
Но это может не сработать так, как вы ожидаете, особенно если используется наследование. Посмотрите на пример:
Вызов
Обходное решение — либо вообще не вызывать
👉@BookPython
multiprocessing
, и в одном из процессов происходит исключение, оно передаётся в основную программу с помощью механизма сериализации (pickling). Исключение сериализуется, передаётся в другой процесс и там десериализуется обратно.Однако сериализация исключений может быть непростой задачей. Исключение создаётся с любым количеством аргументов, которые сохраняются в атрибуте
args
. Эти же аргументы используются при десериализации для воссоздания объекта исключения.Но это может не сработать так, как вы ожидаете, особенно если используется наследование. Посмотрите на пример:
import pickle
class TooMuchWeightError(Exception):
def __init__(self, weight):
super().__init__()
self._weight = weight
pickled = pickle.dumps(TooMuchWeightError(42))
pickle.loads(pickled)
Вызов
TooMuchWeightError.__init__
приводит к вызову Exception.__init__
, который устанавливает args
как пустой кортеж. Этот пустой кортеж затем используется в качестве аргументов при десериализации, что, очевидно, приводит к ошибке:
TypeError: __init__() missing 1 required positional argument: 'weight'
Обходное решение — либо вообще не вызывать
super().__init__()
(что обычно считается плохой практикой при наследовании), либо передавать все аргументы явно в конструктор родительского класса:
class TooMuchWeightError(Exception):
def __init__(self, weight):
super().__init__(weight)
self._weight = weight
👉@BookPython
Python предоставляет мощную библиотеку для работы с датой и временем —
Самым популярным модулем для этой задачи является
Вы не можете просто передать объект временной зоны
Посмотрите на этот смещение
Кроме того, после любых операций с датой и временем, нужно нормализовать объект
Начиная с Python 3.6, рекомендуется использовать
Если вам интересно, почему
👉@BookPython
datetime
. Интересный момент: объекты datetime
имеют специальный интерфейс для поддержки часовых поясов (атрибут tzinfo), однако сама библиотека `datetime
реализует его лишь частично, оставляя остальную работу сторонним модулям.Самым популярным модулем для этой задачи является
pytz
. Хитрость в том, что pytz
не полностью соответствует интерфейсу tzinfo
. В документации pytz
прямо указано с самого начала: «Эта библиотека отличается от задокументированного API Python для реализаций tzinfo
».Вы не можете просто передать объект временной зоны
pytz
в атрибут tzinfo
. Если попробуете, результат может быть абсолютно безумным:
In : paris = pytz.timezone('Europe/Paris')
In : str(datetime(2017, 1, 1, tzinfo=paris))
Out: '2017-01-01 00:00:00+00:09'
Посмотрите на этот смещение
+00:09
. Правильное использование pytz
выглядит так:
In : str(paris.localize(datetime(2017, 1, 1)))
Out: '2017-01-01 00:00:00+01:00'
Кроме того, после любых операций с датой и временем, нужно нормализовать объект
datetime
, если есть вероятность смены смещения (например, на границе перехода на летнее время):
In : new_time = time + timedelta(days=2)
In : str(new_time)
Out: '2018-03-27 00:00:00+01:00'
In : str(paris.normalize(new_time))
Out: '2018-03-27 01:00:00+02:00'
Начиная с Python 3.6, рекомендуется использовать
dateutil.tz
вместо pytz
. Он полностью совместим с tzinfo
, может использоваться напрямую, не требует normalize
, хотя и работает немного медленнее.Если вам интересно, почему
pytz
не поддерживает API datetime
, или вы хотите увидеть больше примеров, обязательно почитайте хорошую статью на эту тему.👉@BookPython
yield from
— элегантная передача управленияЕсли вы пишете генераторы, которые вызывают другие генераторы — забудьте про
for x in sub(): yield x
. Есть способ проще и мощнее.Оператор
yield from
позволяет передавать элементы из подгенератора напрямую, без лишнего кода. Но фишка не только в лаконичности — он также автоматически пробрасывает исключения и возвращаемые значения из подгенератора.Вот классика:
def gen():
for x in range(3):
yield x
def wrapper():
for x in gen():
yield x
Можно короче и лучше:
def wrapper():
yield from gen()
Но главное —
yield from
пробрасывает return-значение из подгенератора (начиная с Python 3.3):
def sub():
yield 1
yield 2
return 'done'
def main():
result = yield from sub()
print('Sub returned:', result)
for _ in main():
pass
# Выведет: Sub returned: done
А ещё через
yield from
можно проксировать значения внутрь генератора — например, в сопрограммах:
def delegator():
result = yield from coroutine()
print('coroutine done:', result)
def coroutine():
x = yield
y = yield
return x + y
g = delegator()
next(g) # Старт
next(g) # coroutine ждет x
g.send(10) # x = 10
print(g.send(20)) # y = 20 → return 30
# Выведет: coroutine done: 30
Итог: если вы пишете генераторы — освоение
yield from
даст вам лаконичный синтаксис, проброс return-значений, исключений и взаимодействие на новом уровне.👉@BookPython
default_factory
в dataclass
: мощнее, чем кажетсяМногие используют
dataclass
как удобный способ задать структуру с полями. Но редко кто по-настоящему раскрывает силу default_factory
. А зря — он спасает от багов и даёт гибкость.Когда нужно задать значение по умолчанию для поля в
dataclass
, логично тянуться к default=
. Но если это изменяемый тип (например, список или словарь) — вас поджидает ловушка.
from dataclasses import dataclass, field
@dataclass
class User:
name: str
tags: list[str] = [] # ⚠️ опасно!
Все экземпляры
User
будут делить один и тот же список. То есть:
a = User("Alice")
b = User("Bob")
a.tags.append("admin")
print(b.tags) # ['admin'] 😱
Вместо этого используйте
default_factory
:
@dataclass
class User:
name: str
tags: list[str] = field(default_factory=list)
Теперь у каждого
User
будет свой список:
a = User("Alice")
b = User("Bob")
a.tags.append("admin")
print(b.tags) # []
Но
default_factory
не только про списки. Это отличный способ задать любое значение "по умолчанию", включая кастомную логику:
import uuid
@dataclass
class Session:
id: str = field(default_factory=lambda: str(uuid.uuid4()))
Или, например, значения из окружения:
import os
@dataclass
class Config:
debug: bool = field(default_factory=lambda: os.getenv("DEBUG") == "1")
Кстати, это ещё и отличное место для внедрения DI:
@dataclass
class Service:
client: "Client" = field(default_factory=create_default_client)
default_factory
— это маленький хак, который позволяет сделать код чище и безопаснее, особенно когда работаешь с изменяемыми структурами или сложной инициализацией.👉@BookPython
Стандартный модуль
👉@BookPython
json
имеет интерфейс командной строки, который может быть полезен для форматирования JSON исключительно средствами Python. Модуль называется json.tool
и вызывается следующим образом:
$ echo '{"a": [], "b": "c"}' | python -m json.tool
{
"a": [],
"b": "c"
}
👉@BookPython
Скрытые фичи
Многие используют
Вот несколько приёмов, которые мало кто использует — но зря.
1. Добавление поведения в Enum
Теперь
2. Enum с полями
3. Автоматические значения с
Удобно, если не важны конкретные значения, а нужны уникальные.
4. Строгая сериализация
В реальных приложениях (API, базы) лучше контролировать сериализацию enum'ов:
5. Сравнение по значению
Итого:
👉@BookPython
Enum
: как выжать максимумМногие используют
Enum
как простой список констант. Но у enum.Enum
в Python есть куда больше возможностей — и они могут сделать код чище и мощнее.Вот несколько приёмов, которые мало кто использует — но зря.
1. Добавление поведения в Enum
from enum import Enum
class Status(Enum):
DRAFT = 'draft'
PUBLISHED = 'published'
ARCHIVED = 'archived'
def is_visible(self):
return self in {Status.DRAFT, Status.PUBLISHED}
Теперь
Status.DRAFT.is_visible()
— это просто и элегантно.2. Enum с полями
from enum import Enum
class Color(Enum):
RED = ('#FF0000', 'danger')
GREEN = ('#00FF00', 'safe')
def __init__(self, hex_code, label):
self.hex_code = hex_code
self.label = label
Color.RED.hex_code # '#FF0000'
Color.RED.label # 'danger'
3. Автоматические значения с
auto()
from enum import Enum, auto
class Role(Enum):
ADMIN = auto()
USER = auto()
GUEST = auto()
Удобно, если не важны конкретные значения, а нужны уникальные.
4. Строгая сериализация
В реальных приложениях (API, базы) лучше контролировать сериализацию enum'ов:
import json
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Enum):
return obj.value
return super().default(obj)
json.dumps(Status.PUBLISHED, cls=CustomEncoder) # "published"
5. Сравнение по значению
Status('draft') == Status.DRAFT # True
Status('draft') is Status.DRAFT # True (enum гарантирует singleton)
Итого:
Enum
— это не просто константы. Это лёгкий способ инкапсулировать поведение и данные, улучшить читаемость и сделать код устойчивее к ошибкам.👉@BookPython
Иногда в программе нужна очередь — контейнер, куда элементы добавляются с одной стороны и извлекаются с другой. В Python для этого можно использовать
Однако
Как видно, операция
Для очередей лучше использовать
👉@BookPython
list
:
In : lst = [1, 2, 3]
In : lst.pop()
Out: 3
In : lst
Out: [1, 2]
In : lst[:0] = [4] # push
In : lst
Out: [4, 1, 2]
Однако
list
выглядит не очень удобно (взгляните на этот "push") и работает неэффективно.
In : lst = [0] * 10_000_000
In : %timeit lst[:0] = [1]
9.5 ms ± 111 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In : %timeit lst.pop()
84.3 ns ± 4.01 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Как видно, операция
pop()
в 100 раз быстрее, чем вставка в начало списка. Это связано с тем, как устроен list
в Python: легко добавлять и удалять элементы с конца, но удаление/добавление в начало требует создания нового списка.Для очередей лучше использовать
collections.deque
. Он специально для этого создан:
In : from collections import deque
In : d = deque([1] * 100_000_000)
In : %timeit d.popleft()
65 ns ± 0.436 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
👉@BookPython
Некоторый код может выводить интересующие вас данные в stdout, вместо того чтобы предоставлять API, возвращающий строку, пригодную для использования в программе.
Вместо рефакторинга такого кода можно воспользоваться менеджером контекста
Также существует
👉@BookPython
Вместо рефакторинга такого кода можно воспользоваться менеджером контекста
contextlib.redirect_stdout
, который позволяет временно перенаправить stdout в любой объект, поддерживающий файловый интерфейс. В сочетании с io.StringIO
это позволяет сохранить вывод в переменную.
from contextlib import redirect_stdout
from io import StringIO
s = StringIO()
with redirect_stdout(s):
print(42)
print(s.getvalue())
Также существует
contextlib.redirect_stderr
для перенаправления вывода sys.stderr
.👉@BookPython
Каждый вызов
Проблема в том, что любое неожиданное
Последний
Однако это поведение было изменено в Python 3.7. Теперь любое внешнее
Такое же поведение можно включить начиная с Python 3.5 с помощью:
👉@BookPython
next(x)
возвращает следующее значение из итератора x
, если только не возникает исключение. Если это StopIteration
, значит, итератор исчерпан и больше не может возвращать значения. При итерации по генератору это исключение выбрасывается автоматически в конце его тела:
>>> def one_two():
... yield 1
... yield 2
...
>>> i = one_two()
>>> next(i)
1
>>> next(i)
2
>>> next(i)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
StopIteration
автоматически обрабатывается инструментами, которые вызывают next
за вас:
>>> list(one_two())
[1, 2]
Проблема в том, что любое неожиданное
StopIteration
, возникшее внутри генератора, приводит к его молчаливому завершению, а не к выбросу исключения:
def one_two():
yield 1
yield 2
def one_two_repeat(n):
for _ in range(n):
i = one_two()
yield next(i)
yield next(i)
yield next(i)
print(list(one_two_repeat(3)))
Последний
yield
здесь — ошибка: StopIteration
вызывается и прерывает list(...)
. В результате получаем [1, 2]
, что может удивить.Однако это поведение было изменено в Python 3.7. Теперь любое внешнее
StopIteration
, возникшее в генераторе, преобразуется в RuntimeError
:
Traceback (most recent call last):
File "test.py", line 10, in one_two_repeat
yield next(i)
StopIteration
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "test.py", line 12, in <module>
print(list(one_two_repeat(3)))
RuntimeError: generator raised StopIteration
Такое же поведение можно включить начиная с Python 3.5 с помощью:
from __future__ import generator_stop
👉@BookPython
Все объекты в Python создаются с помощью вызова метода
Можно подумать, что
👉@BookPython
__new__
. Даже если вы определяете собственный __new__
для своего класса, вам всё равно нужно вызвать super().__new__(...)
.Можно подумать, что
object.__new__
— это базовая реализация, которая отвечает за создание всех объектов. Но это не совсем так. На самом деле существует несколько таких реализаций, и они несовместимы между собой. Например, у dict
есть собственная низкоуровневая реализация __new__
, и объекты типов, унаследованных от dict
, нельзя создать с помощью object.__new__
:
class D(dict):
pass
class A:
pass
object.__new__(A)
# <__main__.A at 0x7f200c8902e8>
object.__new__(D)
# TypeError: object.__new__(D) is not safe,
# use D.__new__()
👉@BookPython
🚀 Подборка Telegram каналов для программистов
Системное администрирование, DevOps 📌
https://www.tg-me.com/bash_srv Bash Советы
https://www.tg-me.com/win_sysadmin Системный Администратор Windows
https://www.tg-me.com/sysadmin_girl Девочка Сисадмин
https://www.tg-me.com/srv_admin_linux Админские угодья
https://www.tg-me.com/linux_srv Типичный Сисадмин
https://www.tg-me.com/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
https://www.tg-me.com/linux_odmin Linux: Системный администратор
https://www.tg-me.com/devops_star DevOps Star (Звезда Девопса)
https://www.tg-me.com/i_linux Системный администратор
https://www.tg-me.com/linuxchmod Linux
https://www.tg-me.com/sys_adminos Системный Администратор
https://www.tg-me.com/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://www.tg-me.com/sysadminof Книги для админов, полезные материалы
https://www.tg-me.com/i_odmin Все для системного администратора
https://www.tg-me.com/i_odmin_book Библиотека Системного Администратора
https://www.tg-me.com/i_odmin_chat Чат системных администраторов
https://www.tg-me.com/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://www.tg-me.com/sysadminoff Новости Линукс Linux
1C разработка 📌
https://www.tg-me.com/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
https://www.tg-me.com/DevLab1C 1С:Предприятие 8
https://www.tg-me.com/razrab_1C 1C Разработчик
https://www.tg-me.com/buh1C_prog 1C Программист | Бухгалтерия и Учёт
https://www.tg-me.com/rabota1C_rus Вакансии для программистов 1С
Программирование C++📌
https://www.tg-me.com/cpp_lib Библиотека C/C++ разработчика
https://www.tg-me.com/cpp_knigi Книги для программистов C/C++
https://www.tg-me.com/cpp_geek Учим C/C++ на примерах
Программирование Python 📌
https://www.tg-me.com/pythonofff Python академия.
https://www.tg-me.com/Библиотека Python разработчика | Книги по питону/com.BookPython Библиотека Python разработчика
https://www.tg-me.com/python_real Python подборки на русском и английском
https://www.tg-me.com/python_360 Книги по Python
Java разработка 📌
https://www.tg-me.com/BookJava Библиотека Java разработчика
https://www.tg-me.com/java_360 Книги по Java Rus
https://www.tg-me.com/java_geek Учим Java на примерах
GitHub Сообщество 📌
https://www.tg-me.com/Githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://www.tg-me.com/database_info Все про базы данных
Мобильная разработка: iOS, Android 📌
https://www.tg-me.com/developer_mobila Мобильная разработка
https://www.tg-me.com/kotlin_lib Подборки полезного материала по Kotlin
Фронтенд разработка 📌
https://www.tg-me.com/frontend_1 Подборки для frontend разработчиков
https://www.tg-me.com/frontend_sovet Frontend советы, примеры и практика!
https://www.tg-me.com/React_lib Подборки по React js и все что с ним связано
Разработка игр 📌
https://www.tg-me.com/game_devv Все о разработке игр
Библиотеки 📌
https://www.tg-me.com/book_for_dev Книги для программистов Rus
https://www.tg-me.com/programmist_of Книги по программированию
https://www.tg-me.com/proglb Библиотека программиста
https://www.tg-me.com/bfbook Книги для программистов
БигДата, машинное обучение 📌
https://www.tg-me.com/bigdata_1 Big Data, Machine Learning
Программирование 📌
https://www.tg-me.com/bookflow Лекции, видеоуроки, доклады с IT конференций
https://www.tg-me.com/rust_lib Полезный контент по программированию на Rust
https://www.tg-me.com/golang_lib Библиотека Go (Golang) разработчика
https://www.tg-me.com/itmozg Программисты, дизайнеры, новости из мира IT
https://www.tg-me.com/php_lib Библиотека PHP программиста 👨🏼💻👩💻
https://www.tg-me.com/nodejs_lib Подборки по Node js и все что с ним связано
https://www.tg-me.com/ruby_lib Библиотека Ruby программиста
https://www.tg-me.com/lifeproger Жизнь программиста. Авторский канал.
QA, тестирование 📌
https://www.tg-me.com/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://www.tg-me.com/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://www.tg-me.com/thehaking Канал о кибербезопасности
https://www.tg-me.com/xakep_2 Хакер Free
Книги, статьи для дизайнеров 📌
https://www.tg-me.com/ux_web Статьи, книги для дизайнеров
Математика 📌
https://www.tg-me.com/Pomatematike Канал по математике
https://www.tg-me.com/phis_mat Обучающие видео, книги по Физике и Математике
https://www.tg-me.com/matgeoru Математика | Геометрия | Логика
Excel лайфхак📌
https://www.tg-me.com/Excel_lifehack
https://www.tg-me.com/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://www.tg-me.com/sysadmin_rabota Системный Администратор
https://www.tg-me.com/progjob Вакансии в IT
Системное администрирование, DevOps 📌
https://www.tg-me.com/bash_srv Bash Советы
https://www.tg-me.com/win_sysadmin Системный Администратор Windows
https://www.tg-me.com/sysadmin_girl Девочка Сисадмин
https://www.tg-me.com/srv_admin_linux Админские угодья
https://www.tg-me.com/linux_srv Типичный Сисадмин
https://www.tg-me.com/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
https://www.tg-me.com/linux_odmin Linux: Системный администратор
https://www.tg-me.com/devops_star DevOps Star (Звезда Девопса)
https://www.tg-me.com/i_linux Системный администратор
https://www.tg-me.com/linuxchmod Linux
https://www.tg-me.com/sys_adminos Системный Администратор
https://www.tg-me.com/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://www.tg-me.com/sysadminof Книги для админов, полезные материалы
https://www.tg-me.com/i_odmin Все для системного администратора
https://www.tg-me.com/i_odmin_book Библиотека Системного Администратора
https://www.tg-me.com/i_odmin_chat Чат системных администраторов
https://www.tg-me.com/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://www.tg-me.com/sysadminoff Новости Линукс Linux
1C разработка 📌
https://www.tg-me.com/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
https://www.tg-me.com/DevLab1C 1С:Предприятие 8
https://www.tg-me.com/razrab_1C 1C Разработчик
https://www.tg-me.com/buh1C_prog 1C Программист | Бухгалтерия и Учёт
https://www.tg-me.com/rabota1C_rus Вакансии для программистов 1С
Программирование C++📌
https://www.tg-me.com/cpp_lib Библиотека C/C++ разработчика
https://www.tg-me.com/cpp_knigi Книги для программистов C/C++
https://www.tg-me.com/cpp_geek Учим C/C++ на примерах
Программирование Python 📌
https://www.tg-me.com/pythonofff Python академия.
https://www.tg-me.com/Библиотека Python разработчика | Книги по питону/com.BookPython Библиотека Python разработчика
https://www.tg-me.com/python_real Python подборки на русском и английском
https://www.tg-me.com/python_360 Книги по Python
Java разработка 📌
https://www.tg-me.com/BookJava Библиотека Java разработчика
https://www.tg-me.com/java_360 Книги по Java Rus
https://www.tg-me.com/java_geek Учим Java на примерах
GitHub Сообщество 📌
https://www.tg-me.com/Githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://www.tg-me.com/database_info Все про базы данных
Мобильная разработка: iOS, Android 📌
https://www.tg-me.com/developer_mobila Мобильная разработка
https://www.tg-me.com/kotlin_lib Подборки полезного материала по Kotlin
Фронтенд разработка 📌
https://www.tg-me.com/frontend_1 Подборки для frontend разработчиков
https://www.tg-me.com/frontend_sovet Frontend советы, примеры и практика!
https://www.tg-me.com/React_lib Подборки по React js и все что с ним связано
Разработка игр 📌
https://www.tg-me.com/game_devv Все о разработке игр
Библиотеки 📌
https://www.tg-me.com/book_for_dev Книги для программистов Rus
https://www.tg-me.com/programmist_of Книги по программированию
https://www.tg-me.com/proglb Библиотека программиста
https://www.tg-me.com/bfbook Книги для программистов
БигДата, машинное обучение 📌
https://www.tg-me.com/bigdata_1 Big Data, Machine Learning
Программирование 📌
https://www.tg-me.com/bookflow Лекции, видеоуроки, доклады с IT конференций
https://www.tg-me.com/rust_lib Полезный контент по программированию на Rust
https://www.tg-me.com/golang_lib Библиотека Go (Golang) разработчика
https://www.tg-me.com/itmozg Программисты, дизайнеры, новости из мира IT
https://www.tg-me.com/php_lib Библиотека PHP программиста 👨🏼💻👩💻
https://www.tg-me.com/nodejs_lib Подборки по Node js и все что с ним связано
https://www.tg-me.com/ruby_lib Библиотека Ruby программиста
https://www.tg-me.com/lifeproger Жизнь программиста. Авторский канал.
QA, тестирование 📌
https://www.tg-me.com/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://www.tg-me.com/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://www.tg-me.com/thehaking Канал о кибербезопасности
https://www.tg-me.com/xakep_2 Хакер Free
Книги, статьи для дизайнеров 📌
https://www.tg-me.com/ux_web Статьи, книги для дизайнеров
Математика 📌
https://www.tg-me.com/Pomatematike Канал по математике
https://www.tg-me.com/phis_mat Обучающие видео, книги по Физике и Математике
https://www.tg-me.com/matgeoru Математика | Геометрия | Логика
Excel лайфхак📌
https://www.tg-me.com/Excel_lifehack
https://www.tg-me.com/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://www.tg-me.com/sysadmin_rabota Системный Администратор
https://www.tg-me.com/progjob Вакансии в IT
Telegram
Bash Советы
🚀 Секреты и советы по Bash
🔹 Полезные трюки, хитрые однострочники и лайфхаки для работы в терминале.
🔹 Автоматизация, скрипты и оптимизация работы в Linux.
🔹 Стать мастером Bash легко – просто подпишись!
💻 Прокачивай терминал вместе с нами! 👇
🔹 Полезные трюки, хитрые однострочники и лайфхаки для работы в терминале.
🔹 Автоматизация, скрипты и оптимизация работы в Linux.
🔹 Стать мастером Bash легко – просто подпишись!
💻 Прокачивай терминал вместе с нами! 👇
Чтобы отсортировать словарь по его значениям, используйте функцию
Однако такая функция уже существует в модуле
Вы также можете сортировать только ключи вместо пар ключ-значение:
И снова, эту лямбду можно заменить уже существующим методом:
👉@BookPython
sorted
с пользовательской функцией ключа:
>>> d = dict(a=1, c=3, b=2)
>>> sorted(d.items(), key=lambda item: item[1])
[('a', 1), ('b', 2), ('c', 3)]
Однако такая функция уже существует в модуле
operator
:
>>> from operator import itemgetter
>>> sorted(d.items(), key=itemgetter(1))
[('a', 1), ('b', 2), ('c', 3)]
Вы также можете сортировать только ключи вместо пар ключ-значение:
>>> sorted(d, key=lambda k: d[k])
['a', 'b', 'c']
И снова, эту лямбду можно заменить уже существующим методом:
>>> sorted(d, key=d.get)
['a', 'b', 'c']
👉@BookPython
Популярный способ объявить абстрактный метод в Python — это выбросить исключение
Хотя этот подход довольно распространён и даже поддерживается IDE (например, PyCharm считает такие методы абстрактными), у него есть недостаток: ошибка возникает только при вызове метода, а не при создании экземпляра класса.
Чтобы избежать этой проблемы, используйте модуль
Также важно помнить, что
👉@BookPython
NotImplementedError
:
def human_name(self):
raise NotImplementedError
Хотя этот подход довольно распространён и даже поддерживается IDE (например, PyCharm считает такие методы абстрактными), у него есть недостаток: ошибка возникает только при вызове метода, а не при создании экземпляра класса.
Чтобы избежать этой проблемы, используйте модуль
abc
:
from abc import ABCMeta, abstractmethod
class Service(metaclass=ABCMeta):
@abstractmethod
def human_name(self):
pass
Также важно помнить, что
NotImplemented
— это не то же самое, что NotImplementedError
. NotImplemented
— это специальное значение (как True
и False), а не исключение. Оно используется, например, в специальных методах (__eq__()
, __add__()
и др.), чтобы сообщить Python, что операция не реализована для данного типа, и попытаться вызвать альтернативный метод (например, если a.__add__(b)
возвращает NotImplemented
, Python попробует вызвать b.__radd__(a)).👉@BookPython
collections.defaultdict
позволяет создать словарь, который возвращает значение по умолчанию, если запрашиваемого ключа нет (вместо того чтобы выбрасывать KeyError). Для создания defaultdict
нужно передать не само значение по умолчанию, а фабрику для его создания.Это позволяет создавать словари с потенциально бесконечным уровнем вложенности, благодаря чему можно делать что-то вроде
d[a][b][c]...[z]
.
>>> def infinite_dict():
... return defaultdict(infinite_dict)
...
>>> d = infinite_dict()
>>> d[1][2][3][4] = 10
>>> dict(d[1][2][3][5])
{}
Такое поведение называется "автовивификацией" (autovivification) — термин пришёл из языка Perl.
👉@BookPython
Как упростить работу с аргументами в командной строке с помощью
Раньше для CLI-приложений на Python я использовал
Вот простой пример:
Теперь можно запускать в терминале:
Что круто:
- Автоматически генерируется
- Пишется почти как обычная функция
- Есть автокомплит в оболочках (bash/zsh)
- Поддержка аннотаций типов и валидации "из коробки"
Если ты всё ещё страдаешь с
👉@BookPython
typer
Раньше для CLI-приложений на Python я использовал
argparse
, потом был click
, но недавно полностью перешёл на typer. Это библиотека от автора FastAPI, и она реально 🔥Вот простой пример:
import typer
app = typer.Typer()
@app.command()
def hello(name: str, age: int = 18):
print(f"Привет, {name}! Тебе {age} лет.")
if __name__ == "__main__":
app()
Теперь можно запускать в терминале:
$ python main.py hello Alice --age 30
Привет, Alice! Тебе 30 лет.
Что круто:
- Автоматически генерируется
--help
- Пишется почти как обычная функция
- Есть автокомплит в оболочках (bash/zsh)
- Поддержка аннотаций типов и валидации "из коробки"
Если ты всё ещё страдаешь с
argparse
, рекомендую попробовать typer
. Особенно если ты уже кайфуешь от FastAPI — синтаксис и подход очень похожи.👉@BookPython
Создание объекта в Python включает два ключевых этапа. Сначала вызывается метод
Однако, если
Важно: не следует создавать экземпляры того же класса в
Пример бесконечной рекурсии:
Пример двойного вызова
Правильный способ:
👉@BookPython
__new__
, который создаёт и возвращает новый объект. Затем вызывается метод __init__
для инициализации состояния этого объекта.Однако, если
__new__
возвращает объект, который не является экземпляром исходного класса, метод __init__
не будет вызван. Это связано с тем, что возвращаемый объект, вероятно, уже создан другим классом, и его __init__
уже был выполнен:
class Foo:
def __new__(cls, x):
return dict(x=x)
def __init__(self, x):
print(x) # Никогда не вызывается
print(Foo(0))
Важно: не следует создавать экземпляры того же класса в
__new__
с использованием обычного конструктора (Foo(...)
). Это может привести к двойному вызову __init__
или даже к бесконечной рекурсии.Пример бесконечной рекурсии:
class Foo:
def __new__(cls, x):
return Foo(-x) # Рекурсия
Пример двойного вызова
__init__
:
class Foo:
def __new__(cls, x):
if x < 0:
return Foo(-x)
return super().__new__(cls)
def __init__(self, x):
print(x)
self._x = x
Правильный способ:
class Foo:
def __new__(cls, x):
if x < 0:
return cls.__new__(cls, -x)
return super().__new__(cls)
def __init__(self, x):
print(x)
self._x = x
👉@BookPython
Встроенные значения
Это означает, что вы обычно работаете с приближениями, а не с точными значениями:
Модуль
Но и этого может быть недостаточно:
Для абсолютно точных вычислений можно использовать модуль
Очевидное ограничение — всё равно приходится использовать приближения для иррациональных чисел, таких как π.
👉@BookPython
float
в Python используют оборудование вашего компьютера напрямую, поэтому любое значение представляется внутренне в виде двоичной дроби.Это означает, что вы обычно работаете с приближениями, а не с точными значениями:
>>> format(0.1, '.17f')
'0.10000000000000001'
Модуль
decimal
позволяет использовать десятичную арифметику с произвольной точностью:
>>> from decimal import Decimal
>>> Decimal(1) / Decimal(3)
Decimal('0.3333333333333333333333333333')
Но и этого может быть недостаточно:
>>> Decimal(1) / Decimal(3) * Decimal(3) == Decimal(1)
False
Для абсолютно точных вычислений можно использовать модуль
fractions
, который хранит любое число как рациональное:
>>> from fractions import Fraction
>>> Fraction(1) / Fraction(3) * Fraction(3) == Fraction(1)
True
Очевидное ограничение — всё равно приходится использовать приближения для иррациональных чисел, таких как π.
👉@BookPython